﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml.Serialization;
using HeadCounter.Armourer.Base;
using MathematicallySafe.HeadCounter.Data.Common;
using MathematicallySafe.HeadCounter.Data.Domain;
using MathematicallySafe.HeadCounter.Data.Interfaces;
using StructureMap;
using StructureMap.Pipeline;

namespace MathematicallySafe.HeadCounter.Data.Models
{
    public class OptionsModel : IOptions
    {
        private bool _isDirty;
        private Options _options;

        public OptionsModel()
        {
            if (File.Exists(Constants.LoottableFileName))
            {
                Load();
            }
            else
            {
                CreateDefault();
            }
        }

        private void CreateDefault()
        {
            _options = new Options()
            {
                GuildName = "<Guild>",
                Region = WowRegion.EU,
                Realm = "<Realm>",
                ShortPeriodLength = 6,
                LongPeriodLength = 12,
                DefaultPeriod = Period.Short,
                iLevelBase = 226,
                iLevelProgression = 245,
                iLevelTierDifference = 13,
                MinAttendancePercent = 50,
                MaxEffectiveAttendancePercent = 90,
                HighAttendancePercentage = 90.0,
                GoodAttendancePercentage = 65.0,
                FairAttendancePercentage = 50.0,
                ReportOptionalRaids = true
            };

            AddDefaultLootOverrides();
        }

        private void AddDefaultLootOverrides()
        {
            // These are "overrides" that we alwyas want to exist.  User should be able to edit these afterwards.

            if (_options.Overrides == null)
            {
                _options.Overrides = new List<LootOverride>();
            }

            // Trophy of the Crusade
            MakeLootOverride(47242, 245, LootSlot.Chest);

            // Head of Onyxia
            MakeLootOverride(49644, 245, LootSlot.Head);

            // Tier 10 Marks
            MakeLootOverride(52025, 264, LootSlot.Chest);
            MakeLootOverride(52026, 264, LootSlot.Chest);
            MakeLootOverride(52027, 264, LootSlot.Chest);

            // Tier 10.5 (Hard mode)
            MakeLootOverride(52028, 277, LootSlot.Chest);
            MakeLootOverride(52029, 277, LootSlot.Chest);
            MakeLootOverride(52030, 277, LootSlot.Chest);

            // Shadowmourne Quest items.
            MakeLootOverride(50226, 277, LootSlot.TwoHand);
            MakeLootOverride(50231, 277, LootSlot.TwoHand);
        }

        private void MakeLootOverride(int id, int iLevel, LootSlot slot)
        {
            if (_options.Overrides.FirstOrDefault(o => o.id == id) == null)
            {
                _options.Overrides.Add(new LootOverride
                {
                    id = id,
                    iLevel = iLevel,
                    Slot = slot
                });
            }
        }

        public string GuildName
        {
            get { return _options.GuildName; }
            set { _options.GuildName = value; }
        }

        public WowRegion Region
        {
            get { return _options.Region; }
            set { _options.Region = value; }
        }

        public string Realm
        {
            get { return _options.Realm; }
            set { _options.Realm = value; }
        }

        public int ShortPeriodLength
        {
            get { return _options.ShortPeriodLength; }
            set { _options.ShortPeriodLength = value; }
        }

        public int LongPeriodLength
        {
            get { return _options.LongPeriodLength; }
            set { _options.LongPeriodLength = value; }
        }

        public Period DefaultPeriod
        {
            get { return _options.DefaultPeriod; }
            set { _options.DefaultPeriod = value; }
        }

        public int iLevelBase
        {
            get { return _options.iLevelBase; }
            set { _options.iLevelBase = value; }
        }

        public int iLevelProgression
        {
            get { return _options.iLevelProgression; }
            set { _options.iLevelProgression = value; }
        }

        public int iLevelTierDifference
        {
            get { return _options.iLevelTierDifference; }
            set { _options.iLevelTierDifference = value; }
        }

        public int MaxEffectiveAttendancePercent
        {
            get { return _options.MaxEffectiveAttendancePercent; }
            set { _options.MaxEffectiveAttendancePercent = value; }
        }

        public int MinAttendancePercent
        {
            get { return _options.MinAttendancePercent; }
            set { _options.MinAttendancePercent = value; }
        }

        public int MinAttendanceCount
        {
            get { return _options.MinAttendanceCount; }
            set { _options.MinAttendanceCount = value; }
        }

        public bool ReportOptionalRaids
        {
            get { return _options.ReportOptionalRaids; }
            set { _options.ReportOptionalRaids = value; }
        }

        public double HighAttendancePercentage
        {
            get { return _options.HighAttendancePercentage; }
            set { _options.HighAttendancePercentage = value; }
        }

        public double GoodAttendancePercentage
        {
            get { return _options.GoodAttendancePercentage; }
            set { _options.GoodAttendancePercentage = value; }
        }

        public double FairAttendancePercentage
        {
            get { return _options.FairAttendancePercentage; }
            set { _options.FairAttendancePercentage = value; }
        }

        public List<LootOverride> Overrides
        {
            get { return _options.Overrides; }
            set { _options.Overrides = value; }
        }

        public bool AutoApplyAttendanceCreditToDeletedRaiders
        {
            get { return _options.AutoApplyAttendanceCreditToDeletedRaiders; }
            set { _options.AutoApplyAttendanceCreditToDeletedRaiders = value; }
        }

        public bool ShowShortPeriodAllAttendance
        {
            get { return _options.ShowShortPeriodAllAttendance; }
            set { _options.ShowShortPeriodAllAttendance = value; }
        }

        public bool ShowShortPeriodAttendance
        {
            get { return _options.ShowShortPeriodAttendance; }
            set { _options.ShowShortPeriodAttendance = value; }
        }

        public bool ShowLongPeriodAttendance
        {
            get { return _options.ShowLongPeriodAttendance; }
            set { _options.ShowLongPeriodAttendance = value; }
        }

        public bool ShowLongPeriodAllAttendance
        {
            get { return _options.ShowLongPeriodAllAttendance; }
            set { _options.ShowLongPeriodAllAttendance = value; }
        }

        public bool ShowLifetimeAttendance
        {
            get { return _options.ShowLifetimeAttendance; }
            set { _options.ShowLifetimeAttendance = value; }
        }

        public bool ShowLifetimeAllAttendance
        {
            get { return _options.ShowLifetimeAllAttendance; }
            set { _options.ShowLifetimeAllAttendance = value; }
        }

        public bool ShowShortPeriodEffectiveAttendance
        {
            get { return _options.ShowShortPeriodEffectiveAttendance; }
            set { _options.ShowShortPeriodEffectiveAttendance = value; }
        }

        public bool ShowLongPeriodEffectiveAttendance
        {
            get { return _options.ShowLongPeriodEffectiveAttendance; }
            set { _options.ShowLongPeriodEffectiveAttendance = value; }
        }

        public bool ShowLifetimeEffectiveAttendance
        {
            get { return _options.ShowLifetimeEffectiveAttendance; }
            set { _options.ShowLifetimeEffectiveAttendance = value; }
        }

        public bool ShowShortPeriodLootCount
        {
            get { return _options.ShowShortPeriodLootCount; }
            set { _options.ShowShortPeriodLootCount = value; }
        }

        public bool ShowLongPeriodLootCount
        {
            get { return _options.ShowLongPeriodLootCount; }
            set { _options.ShowLongPeriodLootCount = value; }
        }

        public bool ShowLifetimeLootCount
        {
            get { return _options.ShowLifetimeLootCount; }
            set { _options.ShowLifetimeLootCount = value; }
        }

        public bool ShowShortPeriodLootValue
        {
            get { return _options.ShowShortPeriodLootValue; }
            set { _options.ShowShortPeriodLootValue = value; }
        }

        public bool ShowLongPeriodLootValue
        {
            get { return _options.ShowLongPeriodLootValue; }
            set { _options.ShowLongPeriodLootValue = value; }
        }

        public bool ShowLifetimeLootValue
        {
            get { return _options.ShowLifetimeLootValue; }
            set { _options.ShowLifetimeLootValue = value; }
        }

        public bool ShowShortPeriodLootRate
        {
            get { return _options.ShowShortPeriodLootRate; }
            set { _options.ShowShortPeriodLootRate = value; }
        }

        public bool ShowLongPeriodLootRate
        {
            get { return _options.ShowLongPeriodLootRate; }
            set { _options.ShowLongPeriodLootRate = value; }
        }

        public bool ShowLifetimeLootRate
        {
            get { return _options.ShowLifetimeLootRate; }
            set { _options.ShowLifetimeLootRate = value; }
        }

        public bool ShowShortPeriodLootWeightedValue
        {
            get { return _options.ShowShortPeriodLootWeightedValue; }
            set { _options.ShowShortPeriodLootWeightedValue = value; }
        }

        public bool ShowLongPeriodLootWeightedValue
        {
            get { return _options.ShowLongPeriodLootWeightedValue; }
            set { _options.ShowLongPeriodLootWeightedValue = value; }
        }

        public bool ShowLifetimeLootWeightedValue
        {
            get { return _options.ShowLifetimeLootWeightedValue; }
            set { _options.ShowLifetimeLootWeightedValue = value; }
        }

        public bool ShowShortPeriodWeightedLootRate
        {
            get { return _options.ShowShortPeriodWeightedLootRate; }
            set { _options.ShowShortPeriodWeightedLootRate = value; }
        }

        public bool ShowLongPeriodWeightedLootRate
        {
            get { return _options.ShowLongPeriodWeightedLootRate; }
            set { _options.ShowLongPeriodWeightedLootRate = value; }
        }

        public bool ShowLifetimeWeightedLootRate
        {
            get { return _options.ShowLifetimeWeightedLootRate; }
            set { _options.ShowLifetimeWeightedLootRate = value; }
        }

        public bool ShowShortPeriodLootPriority
        {
            get { return _options.ShowShortPeriodLootPriority; }
            set { _options.ShowShortPeriodLootPriority = value; }
        }

        public bool ShowLongPeriodLootPriority
        {
            get { return _options.ShowLongPeriodLootPriority; }
            set { _options.ShowLongPeriodLootPriority = value; }
        }

        public bool ShowLifetimeLootPriority
        {
            get { return _options.ShowLifetimeLootPriority; }
            set { _options.ShowLifetimeLootPriority = value; }
        }

        public bool IsDirty
        {
            get { return _isDirty; }
        }

        public bool IsClean
        {
            get { return !_isDirty; }
        }

        public void SetClean()
        {
            _isDirty = false;
        }

        public void SetDirty()
        {
            _isDirty = true;
        }

        private void Load()
        {
            _options = SerialisationHelper.Load<Options>(Constants.OptionsFileName);
        }

        public void Save()
        {
            SerialisationHelper.Save<Options>(Constants.OptionsFileName, _options);
        }

    }
}